/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package spaceconquest3d.battle;

import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.collision.shapes.CapsuleCollisionShape;
import com.jme3.bullet.control.CharacterControl;
import com.jme3.input.InputManager;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.InputListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;

/**
 *
 * @author Michael
 */
public class Player extends Entity implements ActionListener {
    private CharacterControl player;
    private Camera cam;
    private BulletAppState bulletAppState;
    private InputManager inputManager;
    private Vector3f flyDirection = new Vector3f(0.0f, 0.0f, 0.0f);
    private float leftVelocity = 0;
    private float upVelocity = 0;
    private float frontVelocity = 0;
    private boolean front, back, left, right, up, down, rollRight, rollLeft, shoot;
    
    public Player(int id, Vector3f position, Camera cam, BulletAppState bulletAppState, InputManager inputManager) {
        super(id, position);
        this.cam = cam;
        this.bulletAppState = bulletAppState;
        this.inputManager = inputManager;
    }
    
    /**
     * Initialize the player ship.
     */
    private void initPlayer() {
        CapsuleCollisionShape playerShape = new CapsuleCollisionShape(2, 4);
        player = new CharacterControl(playerShape, 0.5f);
        player.setUseViewDirection(true);
        player.setViewDirection(cam.getDirection());
        player.setGravity(0.0f);
        player.setPhysicsLocation(new Vector3f(0.0f, 10.0f, 0.0f));
        bulletAppState.getPhysicsSpace().add(player);
    }

    /**
     * Initialize the input keys.
     */
    private void initKeys() {
        inputManager.addMapping("Left", new KeyTrigger(KeyInput.KEY_A));
        inputManager.addMapping("Right", new KeyTrigger(KeyInput.KEY_D));
        inputManager.addMapping("Front", new KeyTrigger(KeyInput.KEY_W));
        inputManager.addMapping("Back", new KeyTrigger(KeyInput.KEY_S));
        inputManager.addMapping("Up", new KeyTrigger(KeyInput.KEY_R));
        inputManager.addMapping("Down", new KeyTrigger(KeyInput.KEY_F));
        inputManager.addMapping("RollRight", new KeyTrigger(KeyInput.KEY_E));
        inputManager.addMapping("RollLeft", new KeyTrigger(KeyInput.KEY_Q));

        inputManager.addMapping("Shoot", new KeyTrigger(KeyInput.KEY_SPACE));

        inputManager.addListener(this, "Left");
        inputManager.addListener(this, "Right");
        inputManager.addListener(this, "Front");
        inputManager.addListener(this, "Back");
        inputManager.addListener(this, "Up");
        inputManager.addListener(this, "Down");
        inputManager.addListener(this, "RollRight");
        inputManager.addListener(this, "RollLeft");

        inputManager.addListener(this, "Shoot");
    }

    public void simpleUpdate(float tpf) {
        Vector3f camDir = cam.getDirection();
        Vector3f camLeft = cam.getLeft();
        Vector3f camUp = cam.getUp();

        flyDirection.set(0.0f, 0.0f, 0.0f);

        if (left && !right) {
            leftVelocity += 0.001f;
        } else if (right && !left) {
            leftVelocity -= 0.001f;
        } else {
            leftVelocity *= 0.99 * 1;
        }
        leftVelocity = Math.max(leftVelocity, -0.1f);
        leftVelocity = Math.min(leftVelocity, 0.1f);


        if (front && !back) {
            frontVelocity += 0.001f;
        } else if (back && !front) {
            frontVelocity -= 0.001f;
        } else {
            frontVelocity *= 0.99 * 1;
        }
        frontVelocity = Math.max(frontVelocity, -0.2f);
        frontVelocity = Math.min(frontVelocity, 0.2f);

        if (up && !down) {
            upVelocity += 0.001f;
        } else if (down && !up) {
            upVelocity -= 0.001f;
        } else {
            upVelocity *= 0.99 * 1;
        }
        upVelocity = Math.max(upVelocity, -0.1f);
        upVelocity = Math.min(upVelocity, 0.1f);


        flyDirection.addLocal(camLeft.mult(leftVelocity));
        flyDirection.addLocal(camUp.mult(upVelocity));
        flyDirection.addLocal(camDir.mult(frontVelocity));

        player.setWalkDirection(flyDirection);

        if (rollLeft && !rollRight) {
            camUp = camUp.interpolate(camLeft, 0.01f).normalize();
            cam.lookAt(cam.getLocation().add(camDir), camUp);
        } else if (rollRight && !rollLeft) {
            camUp = camUp.interpolate(camLeft.negate(), 0.01f).normalize();
            cam.lookAt(cam.getLocation().add(camDir), camUp);
        }

        player.setViewDirection(cam.getDirection());
        cam.setLocation(player.getPhysicsLocation());


    }

    @Override
    public void onAction(String name, boolean isPressed, float tpf) {
        if (name.equals("Left")) {
            left = isPressed;
        } else if (name.equals("Right")) {
            right = isPressed;
        } else if (name.equals("Front")) {
            front = isPressed;
        } else if (name.equals("Back")) {
            back = isPressed;
        } else if (name.equals("Up")) {
            up = isPressed;
        } else if (name.equals("Down")) {
            down = isPressed;
        } else if (name.equals("RollRight")) {
            rollRight = isPressed;
        } else if (name.equals("RollLeft")) {
            rollLeft = isPressed;
        } else if (name.equals("Shoot")) {
            shoot = isPressed;
        }
    }
}
